package indi.liudalei.biology.config;

import com.alibaba.druid.pool.DruidDataSource;
import net.sf.ehcache.CacheManager;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * Created by 刘大磊 on 2017/8/22 9:02.
 */
@Configuration
@EnableTransactionManagement
@ComponentScan({"indi.liudalei.biology.*.service", "indi.liudalei.biology.*.dao"})
@MapperScan(basePackages = {"indi.liudalei.biology.*.dao"}, sqlSessionFactoryRef = "sqlSessionFactory")
public class RootConfig {
    private static final Logger log = LoggerFactory.getLogger(RootConfig.class);

    @Value("${mail.server.host}")
    private String host;
    @Value("${mail.server.port}")
    private Integer port;
    @Value("${mail.server.username}")
    private String username;
    @Value("${mail.server.password}")
    private String password;
    @Value("${mail.server.default_encoding}")
    private String encoding;
    @Value("${mail.server.smtp.auth}")
    private boolean auth;
    @Value("${jdbc.connection.driver_class}")
    private String driverClass;
    @Value("${jdbc.connection.url}")
    private String jdbcUrl;
    @Value("${jdbc.connection.username}")
    private String jdbcUsername;
    @Value("${jdbc.connection.password}")
    private String jdbcPassword;


    /**
     * 发送邮件
     *
     * @return
     */
    @Bean
    public JavaMailSender javaMailSender() {
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
        javaMailSender.setHost(host);
        javaMailSender.setPort(port);
        javaMailSender.setUsername(username);
        javaMailSender.setPassword(password);
        javaMailSender.setDefaultEncoding(encoding);
        javaMailSender.getJavaMailProperties().put("mail.smtp.auth", auth);
        return javaMailSender;
    }

    @Bean(name = "dataSource", destroyMethod = "close",initMethod = "init")
    public DruidDataSource dataSource() {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setUrl(jdbcUrl);
        druidDataSource.setDriverClassName(driverClass);
        druidDataSource.setUsername(jdbcUsername);
        druidDataSource.setPassword(jdbcPassword);
        druidDataSource.setInitialSize(5);
        druidDataSource.setMinIdle(10);
        druidDataSource.setMaxActive(20);
        //配置获取连接等待超时的时间
        druidDataSource.setMaxWait(60000);
        //配置间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒
        druidDataSource.setTimeBetweenConnectErrorMillis(60000);
        //配置一个连接在池中最小生存的时间，单位是毫秒
        druidDataSource.setMinEvictableIdleTimeMillis(30000);
        druidDataSource.setValidationQuery("SELECT 'x'");
        druidDataSource.setTestWhileIdle(true);
        druidDataSource.setTestOnBorrow(false);
        druidDataSource.setTestOnReturn(false);
        //打开PSCache，并且指定每个连接上PSCache的大小
        druidDataSource.setPoolPreparedStatements(true);
        druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(20);
        try {
            druidDataSource.setFilters("stat");
        } catch (SQLException e) {
            log.error("设置 filter出错", e);
        }
        return druidDataSource;
    }

    /**
     * ehcache配置
     *
     * @return
     */
    @Bean
    public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {
        EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
        ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
        return ehCacheManagerFactoryBean;
    }

    @Bean
    public EhCacheCacheManager ehCacheCacheManager(CacheManager cacheManager) {
        EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager();
        ehCacheCacheManager.setCacheManager(cacheManager);
        ehCacheCacheManager.setTransactionAware(true);
        return ehCacheCacheManager;
    }

    @Bean(name = "sqlSessionFactory")
    @Primary
    public SqlSessionFactory misSqlSessionFactory(@Qualifier("dataSource") DataSource misDataSource)
            throws Exception {
        SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(misDataSource);
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sqlSessionFactory.setConfigLocation(resolver.getResource("classpath:mybatis-config.xml"));
        sqlSessionFactory.setMapperLocations(resolver.getResources("classpath*:indi/liudalei/biology/**/mapper/*Mapper.xml"));
        return sqlSessionFactory.getObject();
    }
    /**
     * 配置事务管理器
     */
    @Bean(name = "transaction")
    @Primary
    public DataSourceTransactionManager transactionManager(@Qualifier("dataSource") DataSource dateSource) throws Exception {
        return new DataSourceTransactionManager(dateSource);
    }

}
